Tweak Accept-Language sorting method to respect RFC 3282.
authorLiangent <liangent@gmail.com>
Mon, 28 May 2012 10:51:53 +0000 (18:51 +0800)
committerLiangent <liangent@gmail.com>
Mon, 28 May 2012 11:03:19 +0000 (19:03 +0800)
Now in Accept-Language handling (in the language converter),
languages appearing earlier in the list are treated as more
preferred languages (variants).

Change-Id: Ic50d01f52dce1ae1f4f4e747d5f8b8399ca03b0b

includes/WebRequest.php

index 39c1b1b..7d0dd4a 100644 (file)
@@ -981,7 +981,8 @@ HTML;
 
        /**
         * Parse the Accept-Language header sent by the client into an array
-        * @return array array( languageCode => q-value ) sorted by q-value in descending order
+        * @return array array( languageCode => q-value ) sorted by q-value in descending order then
+        *                                                appearing time in the header in ascending order.
         * May contain the "language" '*', which applies to languages other than those explicitly listed.
         * This is aligned with rfc2616 section 14.4
         */
@@ -1004,19 +1005,25 @@ HTML;
                        return array();
                }
 
-               // Create a list like "en" => 0.8
-               $langs = array_combine( $lang_parse[1], $lang_parse[4] );
+               $langcodes = $lang_parse[1];
+               $qvalues = $lang_parse[4];
+               $indices = range( 0, count( $lang_parse[1] ) - 1 );
                // Set default q factor to 1
-               foreach ( $langs as $lang => $val ) {
-                       if ( $val === '' ) {
-                               $langs[$lang] = 1;
-                       } elseif ( $val == 0 ) {
-                               unset($langs[$lang]);
+               foreach ( $indices as $index ) {
+                       if ( $qvalues[$index] === '' ) {
+                               $qvalues[$index] = 1;
+                       } elseif ( $qvalues[$index] == 0 ) {
+                               $langcodes[$index] = '';
                        }
                }
 
                // Sort list
-               arsort( $langs, SORT_NUMERIC );
+               array_multisort( $qvalues, SORT_DESC, SORT_NUMERIC, $indices, $langcodes );
+               // Create a list like "en" => 0.8
+               $langs = array_combine( $langcodes, $qvalues );
+               if ( isset( $langs[''] ) ) {
+                       unset( $langs[''] );
+               }
                return $langs;
        }